package cn.jimmie.learn.viewArt.ball;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.WindowManager;

/**
 * function :
 *
 * <p> Create Time: 2018年12月31日 22:39 </p>
 * <p> @author Jimmie.Qian  </p>
 */
public class AssistScrollerView extends AssistBallView implements
        OnScreenChangedObserver, EventSource {
    private final AssistScrollerProcessor mProcessor;
    private final WindowManager.LayoutParams mLayoutParams;
    private final WindowManager mWindowManager;
    // 屏幕宽高, 屏幕变化时将更新
    private int W, H;
    private boolean isAttached;
    private OnEventListener mListener;

    private int lx, ly;
    private int lastLx, lastLy;

    AssistScrollerView(Context context, AssistBallView.Conf conf) {
        super(context, conf);
        mProcessor = new AssistScrollerProcessor(this);

        mLayoutParams = LayoutParamUtils.createLayoutParams(context);
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (mWindowManager == null)
            return;
        H = mWindowManager.getDefaultDisplay().getHeight();
        W = mWindowManager.getDefaultDisplay().getWidth();
    }

    @SuppressLint("ApplySharedPref")
    public void save(boolean fromGC) {
        float pctX = fromGC ? mProcessor.downX : mLayoutParams.x;
        float pctY = fromGC ? mProcessor.downY : mLayoutParams.y;
        pctX = pctX / W;
        pctY = pctY / H;

        SharedPreferences preferences = getContext().getSharedPreferences(getClass().getName(), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putFloat("pctX", pctX);
        editor.putFloat("pctY", pctY);
        editor.commit();
    }

    public void restore() {
        SharedPreferences preferences = getContext().getSharedPreferences(getClass().getName(), Context.MODE_PRIVATE);
        float pctX = preferences.getFloat("pctX", -1);
        float pctY = preferences.getFloat("pctY", -1);
        int x = (int) (pctX * W);
        int y = (int) (pctY * H);
        if (pctX == -1 && pctY == -1) {
            int position = mConf.DIMEN.initPosition;
            // 下边
            if (position == 1) {
                setLayoutXY((W - getSize()) / 2, H - getSize());
            }
            // 右边
            else if (position == 2) {
                setLayoutXY(W - getSize(), (H - getSize()) / 2);
            }
            // 上边
            else if (position == 3) {
                setLayoutXY((W - getSize()) / 2, 0);
            }
            // 左边
            else {
                setLayoutXY(0, (H - getSize()) / 2);
            }
        } else {
            setLayoutXY(x, y);
        }
    }

    /**
     * 添加到window
     */
    public void attachToWindow() {
        if (!isAttached) {
            isAttached = true;
            mWindowManager.addView(this, mLayoutParams);
        }
        mProcessor.moveToEdge();
    }

    /**
     * 从window中移除
     */
    public void detachFromWindow() {
        if (isAttached) {
            mProcessor.release();
            isAttached = false;
            mWindowManager.removeViewImmediate(this);
        }
    }

    /**
     * 设置监听器
     */
    public void setListener(OnEventListener mListener) {
        this.mListener = mListener;
    }

    /**
     * 是否添加到window上
     */
    public boolean isAttached() {
        return isAttached;
    }

    /**
     * 移动到上次的相对位置
     *
     * @param deltaX x上的偏移量
     * @param deltaY y上的偏移量
     */
    @Override
    public void moveBy(int deltaX, int deltaY) {
        if (!isAttached) return;
        lx += deltaX;
        ly += deltaY;
        setLayoutXY(lx, ly);
        mProcessor.handleAngle(lx, ly);
        mOrientation = mProcessor.o;
        rotate(mProcessor.angle, mProcessor.pct);
        if (lastLx == mLayoutParams.x && lastLy == mLayoutParams.y) return;
        lastLx = mLayoutParams.x;
        lastLy = mLayoutParams.y;
        mWindowManager.updateViewLayout(this, mLayoutParams);
    }

    @Override
    public void onLayoutChanged(int width, int height) {
        if (!isAttached || (width == W && height == H)) return;
        W = width;
        H = height;
        mProcessor.moveToEdge();
    }

    @Override
    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouchEvent(MotionEvent event) {
        return mProcessor.handleTouchEvent(event);
    }


    @Override
    public void onScrollOver() {
        if (mListener != null) mListener.onAssistViewScrollOver();
    }

    @Override
    public void onAttachedEdge() {
        if (mListener != null) mListener.onAssistViewAttachedEdge();
    }

    /**
     * 外部需要监听 手指触摸事件, 直接抛给监听器.
     */
    @Override
    public void onClick(boolean lock) {
        if (mListener != null) mListener.onAssistViewClick(lock);
    }

    /**
     * 外部需要监听 手指触摸事件, 处理完状态后抛给监听器.
     */
    @Override
    public void onLongPress(boolean lock) {
        setLock(lock);
        if (mListener != null) mListener.onAssistViewLongClick(lock);
    }

    /**
     * 外部需要监听 手指触摸事件, 直接抛给监听器.
     */
    @Override
    public void onActionUp() {
        if (mListener != null) mListener.onAssistViewActionUp();
    }

    /**
     * 外部需要监听 手指抬起事件, 直接抛给监听器.
     */
    @Override
    public void onActionMove(int x, int y) {
        if (mListener != null) mListener.onAssistViewActionMove(x, y);
    }

    @Override
    public void onEdgeState(int value) {
        alpha(value);
    }

    @Override
    public void onHideChanged(boolean hide) {
        setHide(hide);
    }

    @Override
    public int lx() {
        return lx;
    }

    @Override
    public int ly() {
        return ly;
    }

    @Override
    public int W() {
        return W;
    }

    @Override
    public int H() {
        return H;
    }

    private void setLayoutXY(int x, int y) {
        mLayoutParams.x = lx = x;
        mLayoutParams.y = ly = y;
        int halfSize = getSize() / 2;
        int size = getSize();

        if (x < 0) mLayoutParams.x = 0;
        else if (x > W - size) mLayoutParams.x = W - size;
        if (y < 0) mLayoutParams.y = 0;
        else if (y > H - size) mLayoutParams.y = H - size;

        if (x < -halfSize) lx = -halfSize;
        else if (x > W - halfSize) lx = W - halfSize;
        if (y < -halfSize) ly = -halfSize;
        else if (y > H - halfSize) ly = H - halfSize;
    }

    public interface OnEventListener {
        void onAssistViewClick(boolean lock);

        void onAssistViewLongClick(boolean lock);

        void onAssistViewActionMove(int x, int y);

        void onAssistViewActionUp();

        void onAssistViewScrollOver();

        void onAssistViewAttachedEdge();
    }
}
